package org.xxpay.pay.channel.ysepay;

import org.springframework.stereotype.Service;
import org.xxpay.core.common.constant.PayConstant;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.TransOrder;
import org.xxpay.pay.channel.BaseTransNotify;
import org.xxpay.pay.channel.ysepay.util.SignUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 银盛代付回调
 */
@Service
public class YsepayTransNotifyService extends BaseTransNotify {

    private static final MyLog logger = MyLog.getLog(YsepayTransNotifyService.class);

    @Override
    public String getChannelName() {
        return YsepayConfig.CHANNEL_NAME_YSEPAY;
    }

    @Override
    public String doNotify(Object notifyData) {
        String logPrefix = "【处理银盛代付回调】";
        logger.info("====== 开始处理银盛代付回调通知 ======");
        try {
            HttpServletRequest request = (HttpServletRequest) notifyData;
            Map<String, String> resParams = buildNotifyData(request);  //将参数转换为map格式

            if(resParams == null || resParams.isEmpty()) {
                throw new Exception("reqParams is null or empty");
            }

            String transOrderId = resParams.get("out_trade_no");
            TransOrder transOrder = commonService.transOrderService.findByTransOrderId(transOrderId);
            if(transOrder == null){
                throw new Exception("订单查询失败！");
            }

            YsepayConfig ysepayConfig = new YsepayConfig(getTransParam(transOrder));  //获取银盛配置信息
            String publicCerFilePath = payConfig.getCertRootPath() + File.separator + getChannelName() + File.separator + ysepayConfig.getPublicCerPath();

            //验签
            boolean isTrue = SignUtils.rsaCheckContent(publicCerFilePath, resParams, resParams.get("sign"));
            if(!isTrue){  //验签失败
                throw new Exception("验签失败！");
            }

            logger.info("{}验证支付通知数据及签名通过", logPrefix);

            // 获取通知请求参数
            String tradeStatus = resParams.get("trade_status");
            if("TRADE_ACCEPT_SUCCESS".equals(tradeStatus)){ //受理成功， 需要再次查询
                logger.info("{} >>> 处理中，需要再次查询", logPrefix);
                return PayConstant.RETURN_ALIPAY_VALUE_FAIL;

            }else if("TRADE_SUCCESS".equals(tradeStatus)){ //交易成功
                logger.info("{} >>> 转账成功", logPrefix);

                return updateConfirmSuccess(transOrder, null) ?
                        PayConstant.RETURN_ALIPAY_VALUE_SUCCESS : PayConstant.RETURN_ALIPAY_VALUE_FAIL;


            }else if("TRADE_FAILURE".equals(tradeStatus) || "DISHONOUR_SUCCESS".equals(tradeStatus)){  //交易失败 || 退票成功
                logger.info("{} >>> 转账失败", logPrefix);
                return updateConfirmFail(transOrder, null, tradeStatus, resParams.get("trade_status_description")) ?
                        PayConstant.RETURN_ALIPAY_VALUE_SUCCESS : PayConstant.RETURN_ALIPAY_VALUE_FAIL;

            }else{
                logger.info("{} >>> 结果未知, 等待下次查询。 tradeStatus={}", logPrefix, tradeStatus);
                return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
            }

        } catch (Exception e) {
            logger.error(e, logPrefix + "处理异常");
            return PayConstant.RETURN_ALIPAY_VALUE_FAIL;
        }
    }

    //将请求参数转换为 map格式
    public Map buildNotifyData(HttpServletRequest request) {
        Map<String,String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        return params;
    }
}
